package controller

import (
	myConfig "common/config"
	"common/helper"
	myredis "common/redis"
	myUserHelp "common/userHelp"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"member/model"
	"strconv"
	"time"
)

type PiggyBankController struct{}

type RecPiggyBankItem struct {
	Uid       string  `json:"uid" cbor:"uid" db:"uid"`
	Amount    float64 `json:"amount" cbor:"amount" db:"amount"`
	Type      int32   `json:"type" cbor:"type" db:"type"`
	CreatedAt int32   `json:"created_at" cbor:"created_at" db:"created_at"`
}

/*
领取当前利息
*/
func (that PiggyBankController) AchieveInterest(ctx *fasthttp.RequestCtx) {

	if myConfig.IsActiveOpen(myConfig.ActiveType_PiggyBank) == 0 {
		return
	}

	valUid := model.GetUidFromToken(ctx)
	if valUid == "" {
		helper.Print(ctx, false, helper.AccessTokenExpires)
		return
	}

	lk := fmt.Sprintf("w:%s", myUserHelp.GetMemberName(valUid))
	err := model.WithLock(lk)
	if err != nil {
		helper.Print(ctx, false, errors.New(helper.AccessTokenExpires))
		return
	}

	defer model.Unlock(lk)

	if !myUserHelp.CanAchieveInterest(valUid) {
		helper.Print(ctx, false, errors.New(helper.BAN_INTEREST_TODAY))
		return
	}

	PBInterest := myUserHelp.GetInterest(valUid)

	myUserHelp.AddInterest(valUid, -PBInterest)
	myUserHelp.AddTotalInterest(valUid, PBInterest)

	RecPiggyBank := RecPiggyBankItem{
		Uid:       valUid,
		Amount:    PBInterest,
		Type:      2,
		CreatedAt: int32(time.Now().Unix()),
	}

	sqlLog, _, _ := g.Dialect("mysql").Insert("tbl_rec_piggybank_change").Rows(&RecPiggyBank).ToSQL()
	myredis.AddLogToRedis(sqlLog)

	myUserHelp.AddBalanceTransactionRecord(valUid, PBInterest, helper.TransactionPiggyInterest, "0", helper.GenId(), 0.00, "", "", 0)
	myUserHelp.AddUserWageItem(valUid, PBInterest, helper.TransactionPiggyInterest)
	myUserHelp.AddUserBalanceByFloat64(valUid, PBInterest)

	//领取前N天的利息 重新计算是否可以产生新的利息
	myUserHelp.GenInterest(valUid)
	helper.Print(ctx, true, PBInterest)
}

/*
查询玩家储蓄罐信息
*/

type PiggyBankInfo struct {
	Return             float64 `json:"Return" cbor:"Return" db:"Return"` //回报率 5
	PiggyAmount        float64 `json:"PiggyAmount" cbor:"PiggyAmount" db:"PiggyAmount"`
	Interest           float64 `json:"Interest" cbor:"Interest" db:"Interest"`
	TotalInterest      float64 `json:"TotalInterest" cbor:"TotalInterest" db:"TotalInterest"`
	CanAchieveInterest int     `json:"CanAchieveInterest" cbor:"CanAchieveInterest" db:"CanAchieveInterest"`
	InterestCalcTime   int     `json:"InterestCalcTime" cbor:"InterestCalcTime" db:"InterestCalcTime"`
}

func (that PiggyBankController) QueryInterest(ctx *fasthttp.RequestCtx) {
	valUid := model.GetUidFromToken(ctx)
	if valUid == "" {
		helper.Print(ctx, false, errors.New(helper.AccessTokenExpires))
		return
	}

	lk := fmt.Sprintf("w:%s", myUserHelp.GetMemberName(valUid))
	err := model.WithLock(lk)
	if err != nil {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	defer model.Unlock(lk)

	myUserHelp.GenInterest(valUid)
	PBInterest := myUserHelp.GetInterest(valUid)

	var tPiggyInfo PiggyBankInfo
	tPiggyInfo.Interest = PBInterest
	tPiggyInfo.TotalInterest = myUserHelp.GetTotalInterest(valUid)
	tPiggyInfo.Return = myConfig.GetGameCfgFloat64(myConfig.CfgPiggyBankReturn)
	tPiggyInfo.PiggyAmount = myUserHelp.GetPiggyAmount(valUid)
	tPiggyInfo.InterestCalcTime = int(myUserHelp.GetInterestCalcTime(valUid))
	if myUserHelp.CanAchieveInterest(valUid) {
		tPiggyInfo.CanAchieveInterest = 1
	} else {
		tPiggyInfo.CanAchieveInterest = 0
	}

	helper.Print(ctx, true, tPiggyInfo)
}

/*
储蓄罐提现 钱从储蓄罐转到钱包
*/
func (that PiggyBankController) PBWithdraw(ctx *fasthttp.RequestCtx) {
	valUid := model.GetUidFromToken(ctx)
	if valUid == "" {
		helper.Print(ctx, false, helper.AccessTokenExpires)
		return
	}

	lk := fmt.Sprintf("w:%s", myUserHelp.GetMemberName(valUid))
	err := model.WithLock(lk)
	if err != nil {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	defer model.Unlock(lk)

	Amount, _ := strconv.ParseFloat(string(ctx.FormValue("amount")), 64)

	PiggyAmount := myUserHelp.GetPiggyAmount(valUid)
	if Amount > PiggyAmount || Amount <= 0.00 {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	//判断密码
	ctxPayP := string(ctx.FormValue("payp"))
	PayPassword := myUserHelp.GetMemberPayPsw(valUid)
	if PayPassword == "0" || PayPassword == "" {
		helper.Print(ctx, false, helper.SetWithdrawPwdFirst)
		return
	}

	if ctxPayP == "" {
		helper.Print(ctx, false, helper.WithdrawPwdMismatch)
		return
	}

	if ctxPayP != PayPassword {
		helper.Print(ctx, false, helper.WithdrawPwdMismatch)
		return
	}

	myUserHelp.AddPiggyAmount(valUid, -Amount)

	RecPiggyBank := RecPiggyBankItem{
		Uid:       valUid,
		Amount:    Amount,
		Type:      0,
		CreatedAt: int32(time.Now().Unix()),
	}

	sqlLog, _, _ := g.Dialect("mysql").Insert("tbl_rec_piggybank_change").Rows(&RecPiggyBank).ToSQL()
	myredis.AddLogToRedis(sqlLog)

	myUserHelp.AddBalanceTransactionRecord(valUid, Amount, helper.TransactionFromPiggy, "0", helper.GenId(), 0.00, "", "", 0)
	myUserHelp.AddUserBalanceByFloat64(valUid, Amount)

	helper.Print(ctx, true, helper.Success)
}

/*
储蓄罐充值 钱从钱包转到储蓄罐
*/
func (that PiggyBankController) PBDeposit(ctx *fasthttp.RequestCtx) {
	valUid := model.GetUidFromToken(ctx)
	if valUid == "" {
		helper.Print(ctx, false, helper.AccessTokenExpires)
		return
	}

	lk := fmt.Sprintf("w:%s", myUserHelp.GetMemberName(valUid))
	err := model.WithLock(lk)
	if err != nil {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	defer model.Unlock(lk)

	Amount, _ := strconv.ParseFloat(string(ctx.FormValue("amount")), 64)

	if Amount < myConfig.GetGameCfgFloat64(myConfig.CfgMinPiggy) {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	if Amount > myUserHelp.GetBalanceFloat64ByUid(valUid) {
		helper.Print(ctx, false, helper.AmountErr)
		return
	}

	myUserHelp.AddPiggyAmount(valUid, Amount)

	RecPiggyBank := RecPiggyBankItem{
		Uid:       valUid,
		Amount:    Amount,
		Type:      1,
		CreatedAt: int32(time.Now().Unix()),
	}

	sqlLog, _, _ := g.Dialect("mysql").Insert("tbl_rec_piggybank_change").Rows(&RecPiggyBank).ToSQL()
	myredis.AddLogToRedis(sqlLog)

	myUserHelp.AddBalanceTransactionRecord(valUid, -Amount, helper.TransactionToPiggy, "0", helper.GenId(), 0.00, "", "", 0)
	myUserHelp.AddUserBalanceByFloat64(valUid, -Amount)

	helper.Print(ctx, true, helper.Success)
}

/*
储蓄罐充值 提现 记录
*/
func (that PiggyBankController) PBChangeRec(ctx *fasthttp.RequestCtx) {
	valUid := model.GetUidFromToken(ctx)
	if valUid == "" {
		helper.Print(ctx, false, helper.AccessTokenExpires)
		return
	}

	flag := ctx.QueryArgs().GetUintOrZero("flag")      //查询时间 0 所有 ,1 昨天, 2 今天,3 7天, 4 15天,5 30天
	Querytype := ctx.QueryArgs().GetUintOrZero("type") //查询时间 0:储蓄罐转到钱包 1(钱包转到储蓄罐) 2 利息  否则所有
	now := time.Now()
	loc, _ := time.LoadLocation("America/Sao_Paulo")
	var startTime, endTime int64
	switch flag {
	case 1:
		// Yesterday
		startTime = time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, loc).Unix()
		endTime = time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, loc).Unix()
	case 2:
		// Today
		startTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).Unix()
		endTime = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, loc).Unix()
	case 3:
		// Last 7 days
		startTime = time.Date(now.Year(), now.Month(), now.Day()-6, 0, 0, 0, 0, loc).Unix()
		endTime = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, loc).Unix()
	case 4:
		// Last 15 days
		startTime = time.Date(now.Year(), now.Month(), now.Day()-14, 0, 0, 0, 0, loc).Unix()
		endTime = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, loc).Unix()
	case 5:
		// Last 30 days
		startTime = time.Date(now.Year(), now.Month(), now.Day()-29, 0, 0, 0, 0, loc).Unix()
		endTime = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, loc).Unix()
	default:
		// All time
		startTime = 0
		endTime = 0
	}

	SqlSelect := fmt.Sprintf("Select uid,created_at,amount,type from tbl_rec_piggybank_change where uid = %s", valUid)

	if startTime != 0 && endTime != 0 {
		SqlSelect += fmt.Sprintf(" and created_at>=%d and created_at<=%d", startTime, endTime)
	}

	if Querytype == 0 || Querytype == 1 || Querytype == 2 {
		SqlSelect += fmt.Sprintf(" and type=%d ", Querytype)
	}

	// add order by
	SqlSelect += " order by created_at desc"

	var lstPiggyBank []RecPiggyBankItem
	model.GetSlaveDBInstance().Select(&lstPiggyBank, SqlSelect)
	helper.Print(ctx, true, lstPiggyBank)
}
